﻿#define _CRT_SECURE_NO_WARNINGS 1

#include<iostream>

//展开命名空间 using
using namespace std;


//第一个C++程序
//int main()
//{
//	cout << "hello world\n" << endl;
//	int i = 9;
//	int n = 7;
//	cout << i << "\n" << n << "\n";
//	cin >> i >> n;
//	cout << i << " " << n << "\n" << endl;
//
//	return 0;
//}

// 命名空间 namespace 命名一个域来定义各种变量 
// 使用指定域运算符 :: 来访问其内部变量 解决了命名冲突的问题

//int main()
//{
//	cout << "xxx" << endl;
//	//在io需求比较高的时候 可以加上以下三行代码提高效率
//  
//	ios_base::sync_with_stdio(false);
//	cin.tie(nullptr);
//	cout.tie(nullptr);
//
//	return 0;
//}

// 缺省参数 ---- 默认参数
// 全缺省 ----
void Func1(int a = 20, int b = 30, int c = 40)
{
	cout << "a = " << a << endl;
	cout << "b = " << b << endl;
	cout << "c = " << c << endl << endl;
}

//void Func(int a = 0)//a的默认值为0
//{
//	cout << a << endl;
//}

// 半缺省 ---- 从左往右依次缺省

//int main()
//{
//	Func(1);
//	Func1(1, 2, 3);
//	Func1(1, 2);
//	Func1(1);
//	Func1();
//
//	return 0;
//}

// 函数重载 ---- 可以使用相同的函数名 编译时自动识别所调用函数
// 同一作用域下 同一函数名不同参数类型或个数可以构成函数重载

// 引用 ---- 给已经存在的变量取另外的名字
// 引用在定义时必须初始化
// 一个变量可以有多个引用
// 一个引用一旦引用一个实体后就不能改变其引用对象
// 使用场景 ---- 在一定情况下替代指针
// 
//int main()
//{
//	int i = 0;
//	cout << &i << endl;//取地址
//	int& j = i;//j 是 i 的引用
//	cout << &j << endl;//此时打印地址发现 i j 的地址相同
//	
//	int m = 20;
//	j = m;//将 m 赋值给 j
//
//	return 0;
//}

void Swap(int& rx, int& ry)
{
	int tmp = rx;
	rx = ry;
	ry = tmp;
}

void Swap(int* rx, int* ry)
{
	int tmp = *rx;
	*rx = *ry;
	*ry = tmp;
}

// 引用无法改变指向 所以无法完全代替指针
//int main()
//{
//	int x = 0, y = 1;
//	cout << x << " " << y << endl;
//
//	Swap(x, y);
//	cout << x << " " << y << endl;
//
//	return 0;
//}

// 引用可以作为返回值 ---- 可能会造成野指针的访问

// 错误示例 ----
// 返回引用的使用场景 ---- static 修饰的变量 malloc 申请的变量 等
// 返回引用可以直接修改引用对象 ---- 相当于读写双向接口

int& Func()
{
	int ret = 0;
	cout << &ret << endl;

	return ret;
}

//int main()
//{
//	int& x = Func();
//	cout << &x << endl;
//
//	return 0;
//}

// const 引用

//int main()
//{
//	const int a = 0;
//	//int& b = a; // X 权限放大
//	const int& b = a;// ✔
//	
//	int c = 0;
//	const int& d = c;// ✔ 权限缩小
//
//	const int* p1 = &a;
//	//int* p2 = p1;// X 权限放大
//
//	int* p3 = &c;
//	const int* p4 = p3; //✔ 权限缩小
//
//	return 0;
//}

//int main()
//{
//	int i = 1;
//	double d = i;
//
//	//double& rd = i; // X 类似于权限放大
//	const double& rd = i; // ✔
//	//临时变量具有常性 类似于被 const 修饰
//
//	return 0;
//}

// 宏函数很复杂 容易写出问题 还不能调试
// 优点 高频调用的小函数写成宏函数可以提高效率
// C++建议 const enum inline 替代宏
// ADD的宏函数
#define ADD(x,y) ((x)+(y))

// 内联函数 inline 修饰的函数在预处理时会被特殊处理 使其调用时不用创建栈帧
// 内联对编译器仅仅只是个建议 
inline int Add(int x, int y)
{
	return x + y;
}

//int main()
//{
//	int ret = Add(1, 2);
//	cout << ret << endl;
//
//	return 0;
//}

// nullptr 空指针关键字
//
//int main()
//{
//	static int a = 0;
//	return 0;
//}